package wang.hex.codetransfer.image;

import wang.hex.codetransfer.code.gui.CodeImageGui;
import wang.hex.codetransfer.code.gui.SnapShot;

import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * @Author wujie
 * @Class ImageCreate
 * @Description
 * @Date 2021/1/26 13:53
 */
public class ImageCreate {
    public static int getRGBFromBytes(byte r, byte g, byte b) {

        return ((0xFF << 24) | ((r + 128) << 16) | ((g + 128) << 8) | (b + 128));
    }

    public static void setRGBToBytes(byte[] bytes, int start, int RGB) {
        bytes[start] = (byte) (((RGB & 0xff0000) >> 16) - 128);
        bytes[start + 1] = (byte) (((RGB & 0xff00) >> 8) - 128);
        bytes[start + 2] = (byte) ((RGB & 0xff) - 128);
    }

    public static int getIntFromBytes(byte[] bytes, int start) {
        int i = (bytes[start] & 0xFF);
        i = (i << 8) | (bytes[start + 1] & 0xFF);
        i = (i << 8) | (bytes[start + 2] & 0xFF);
        i = (i << 8) | (bytes[start + 3] & 0xFF);
        return i;
    }

    public static void setIntToBytes(byte[] bytes, int start, int value) {
        bytes[start] = (byte) ((value >> 24) & 0xFF);
        bytes[start + 1] = (byte) ((value >> 16) & 0xFF);
        bytes[start + 2] = (byte) ((value >> 8) & 0xFF);
        bytes[start + 3] = (byte) (value & 0xFF);
    }


    public static BufferedImage encodeToImage(byte[] bytes, int width, int height) {
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        int length = bytes.length;
        byte[] lenByte = new byte[4];
        setIntToBytes(lenByte, 0, length);
        bufferedImage.setRGB(0, 0, getRGBFromBytes(lenByte[0], lenByte[1], lenByte[2]));
        int x = 1;
        int y = 0;
        for (int i = -1; i < bytes.length; i = i + 3) {
            int rgb = getRGBFromBytes(i == -1 ? lenByte[3] : bytes[i], i + 1 < bytes.length ? bytes[i + 1] : 0, i + 2 < bytes.length ? bytes[i + 2] : 0);
            bufferedImage.setRGB(x, y, rgb);
            x++;
            if (x == bufferedImage.getWidth()) {
                x = 0;
                y++;
            }
        }
        return bufferedImage;
    }

    public static byte[] decodeToByte(BufferedImage bufferedImage) {
        int rgb = bufferedImage.getRGB(0, 0);
        int rgb1 = bufferedImage.getRGB(1, 0);
        byte[] bytes = new byte[6];
        setRGBToBytes(bytes, 0, rgb);
        setRGBToBytes(bytes, 3, rgb1);
        int len = getIntFromBytes(bytes, 0);
        byte[] data = new byte[len];
        if (len > 0) {
            data[0] = bytes[4];
        }
        if (len > 1) {
            data[1] = bytes[5];
        }
        int x = 2;
        int y = 0;
        int index = 2;
        while (x < bufferedImage.getWidth() && y < bufferedImage.getHeight()) {

            int rgb2 = bufferedImage.getRGB(x, y);
            byte[] bytes1 = new byte[3];
            setRGBToBytes(bytes1, 0, rgb2);
            for (byte b : bytes1) {
                if (index < len) {
                    data[index] = b;
                    index++;
                } else {
                    return data;
                }
            }
            x++;
            if (x == bufferedImage.getWidth()) {
                x = 0;
                y++;
            }
        }
        return data;
    }


    public static void main(String[] args) {
        BufferedImage bufferedImage = encodeToImage("我大视挨打".getBytes(), 100, 100);
        ImageGui of = ImageGui.of(0, 0, 100, 100);
        of.setImage(bufferedImage);
        BufferedImage bufferedImage1 = SnapShot.snapShot(0, 0, 100, 100);
        byte[] bytes = decodeToByte(bufferedImage1);
        System.out.println(new String(bytes));

    }
}
